package com.tao.lab.power.usb.driver;


import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.util.Log;

import com.tao.lab.power.usb.model.DeviceType;
import com.tao.lab.power.usb.UsbSerialDriver;
import com.tao.lab.power.usb.UsbSerialIOListener;
import com.tao.lab.power.usb.UsbSerialIOManager;
import com.tao.lab.power.usb.UsbSerialPort;
import com.tao.lab.power.usb.model.UsbSerialStatus;

/**
 * title: 传感器管理
 * description: 状态、读写管理
 * @author gongmin.li
 * @version 1.0.0
 * @since 2020-05-14
 */
public class UsbSerialDevice {
    /** 串口写数据超时. */
    public static final int WRITE_WAIT_MILLIS = 500;

    private static final String TAG = UsbSerialDevice.class.getSimpleName();

    private DeviceType mDeviceType;
    private UsbManager mUsbManager;
    private UsbSerialProber mUsbDefaultProber;
    private UsbDevice mDevice;

    private int mPortNum;
    private int mBaudRate;

    private UsbSerialPort mUsbSerialPort;
    private UsbSerialIOListener mUsbSerialIOListener;
    private UsbSerialIOManager mUsbIOManager;

    private volatile UsbSerialStatus mUsbSerialStatus = UsbSerialStatus.NONE;

    public DeviceType getSerialType() {
        return mDeviceType;
    }

    public synchronized UsbSerialStatus getSensorStatus() {
        return mUsbSerialStatus;
    }

    public synchronized void setSensorStatus(UsbSerialStatus mUsbSerialStatus) {
        this.mUsbSerialStatus = mUsbSerialStatus;
    }

    public UsbSerialIOListener getSerialIOListener() {
        return mUsbSerialIOListener;
    }

    public UsbSerialDevice(DeviceType deviceType, UsbManager usbManager, UsbSerialProber usbSerialProber,
                           UsbSerialIOListener listener, int baudRate, int portNum) {
        mDeviceType = deviceType;
        mUsbManager = usbManager;
        mUsbDefaultProber = usbSerialProber;
        mUsbSerialIOListener = listener;
        mBaudRate = baudRate;
        mPortNum = portNum;
    }

    public void init(UsbDevice device) {
        if (null == mDevice) {
            mDevice = device;
        }
    }

    public boolean serialOpen() {
        try {

            if (null == mDevice) {
                setSensorStatus(UsbSerialStatus.SERIAL_PORT_FAIL);
                return false;
            }

            if (getSensorStatus().getEnumPriority() >= UsbSerialStatus.SERIAL_PORT_OK.getEnumPriority()) {
                return true;
            }

            UsbSerialDriver driver = mUsbDefaultProber.probeDevice(mDevice);
            if (driver == null) {
                Log.e(TAG, "serialOpen: 已知设备，未找到驱动");
                setSensorStatus(UsbSerialStatus.SERIAL_PORT_FAIL);
                return false;
            }
            UsbDeviceConnection usbConnection = mUsbManager.openDevice(driver.getDevice());

            mUsbSerialPort = driver.getPorts().get(mPortNum);
            mUsbSerialPort.open(usbConnection);
            //int mBaudRate, int dataBits, int stopBits, int parity
            mUsbSerialPort.setParameters(mBaudRate,
                    UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

            mUsbIOManager = new UsbSerialIOManager(mUsbSerialPort, mUsbSerialIOListener, getSensorStatus());


            Log.d(TAG, "serialOpen: 打开成功：" + mDeviceType.getEnumName());
        } catch (Exception e) {
            Log.e(TAG, "serialOpen: 打开失败" + mDeviceType.getEnumName() + " 原因：", e);
            setSensorStatus(UsbSerialStatus.SERIAL_PORT_FAIL);
            return false;
        }

        setSensorStatus(UsbSerialStatus.SERIAL_PORT_OK);
        return true;
    }

    public void serialDestory() {

        setSensorStatus(UsbSerialStatus.SERIAL_CLOSE);
        mUsbIOManager.stop();
        mUsbSerialIOListener.clearData();
        try {
            mUsbSerialPort.close();
        } catch (Exception e) {
            //e.printStackTrace();
        }
        mDevice = null;

    }

    public int writeInitDataFixedSend() {
        return write(mUsbSerialIOListener.initDataFixedSend());
    }

    public int write(final byte[] src) {
        try {

            if (getSensorStatus().getEnumPriority() < UsbSerialStatus.SERIAL_PORT_OK.getEnumPriority()) {
                return -1;
            }

            int writeResult = mUsbSerialPort.write(src, WRITE_WAIT_MILLIS);
            //Log.d(TAG, mDeviceType.getEnumName() + " write src===" + CartByteHexStringUtil.byte2HexString(src)
            //        + " &length=" + src.length
            //        + " &writeResult=" + writeResult);

            return writeResult;
        } catch (Exception e) {
            Log.e(TAG, mDeviceType.getEnumName() + " write: 数据发送异常：", e);
        }
        return -1;
    }

}
